package org.ccay.async.conduit;

import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Session;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

import org.ccay.async.AsyncMessage;
import org.ccay.core.exception.ApplicationException;
import org.ccay.core.log.ILogger;
import org.ccay.core.log.CcayLoggerFactory;

/**
 * 异步通道的JMS实现。
 * 
 * 负责将异步消息转换成JMS Message，并利用JmsTemplate发送到JMS队列中。
 * 
 * 
 * @since Dec 6, 2011
 */
public class JmsConduit extends AbstractAsyncConduit implements InitializingBean {
	
	/** 日志记录器 **/
	private ILogger log = CcayLoggerFactory.getLogger(JmsConduit.class);
	
	/** Message Broker连接工厂 **/
	private ConnectionFactory connectionFactory;
	
	/** 消息的目的地 **/
	private Destination destination;
	
	/** JmsTemplate，用于发送JMS消息 **/
	private JmsTemplate jmsTemplate;
	
	/**
	 * 设置Message Broker连接工厂
	 * 	
	 * 
	 * @since Dec 7, 2011
	 * @param connectionFactory
	 */
	public void setConnectionFactory(ConnectionFactory connectionFactory) {
		this.connectionFactory = connectionFactory;
	}
	
	/**
	 * 设置消息目的地。
	 * 
	 * 
	 * @since Dec 7, 2011
	 * @param destination
	 */
	public void setDestination(Destination destination) {
		this.destination = destination;
	}
	
	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	public void afterPropertiesSet() throws ApplicationException {
		assert(this.connectionFactory != null);
		assert(this.destination != null);
		
		// 创建一个JmsTemplate
		this.jmsTemplate = new JmsTemplate(this.connectionFactory);
		this.jmsTemplate.setDefaultDestination(this.destination);
	}

	/* (non-Javadoc)
	 * @see org.ccay.core.async.AsyncConduit#handle(org.ccay.core.async.Message)
	 */
	public void handle(final AsyncMessage message) {
		log.debug("Ready to send async message ["+message.getType()+"] to destination: "+this.jmsTemplate.getDefaultDestination().toString());
		log.debug("Destination Class: "+ this.jmsTemplate.getDefaultDestination().getClass());
		 
		jmsTemplate.send(new MessageCreator() {
			
			/* (non-Javadoc)
			 * @see org.springframework.jms.core.MessageCreator#createMessage(javax.jms.Session)
			 */
			public javax.jms.Message createMessage(Session session) throws JMSException {
				return session.createObjectMessage(message);
			}
		});
	}

//	private void print() {
//		Class c = this.jmsTemplate.getDefaultDestination().getClass() ;
//		while(c != null){
//			log.debug("jmsTemplate.getDefaultDestination().getClass(): "+ c);
//			
//			Class[] interfaces = c.getInterfaces();
//			if(interfaces != null){
//				for(Class in: interfaces){
//					log.debug("intefaces: "+ in);
//				}
//			}
//			
//			c = c.getSuperclass();
//		}
//	}

	/* (non-Javadoc)
	 * @see org.ccay.core.async.AbstractAsyncConduit#accept(org.ccay.core.async.Message)
	 */
	@Override
	public boolean accept(AsyncMessage message) {
		return super.accept(message);
	}

}